<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Java强大的Stream API | Kylin</title><meta name="keywords" content="Java,Java8"><meta name="author" content="Kylin"><meta name="copyright" content="Kylin"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Stream API说明Java8中有两大最为重要的改变。第一个是Lambda 表达式;另外一个则是 Stream API。 Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这 是目前为止对Java类库最好的补充，因为Stream API可以极大提供Java程序员的生产力，让程序员写出高效率、干净、简洁的代码。 Stream 是 Java8 中">
<meta property="og:type" content="article">
<meta property="og:title" content="Java强大的Stream API">
<meta property="og:url" content="https://www.codekylin.cn/27286.html">
<meta property="og:site_name" content="Kylin">
<meta property="og:description" content="Stream API说明Java8中有两大最为重要的改变。第一个是Lambda 表达式;另外一个则是 Stream API。 Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这 是目前为止对Java类库最好的补充，因为Stream API可以极大提供Java程序员的生产力，让程序员写出高效率、干净、简洁的代码。 Stream 是 Java8 中">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://qiniu.codekylin.cn/github/img/img/博客封面19.png">
<meta property="article:published_time" content="2020-12-23T07:55:01.000Z">
<meta property="article:modified_time" content="2022-07-12T11:42:50.033Z">
<meta property="article:author" content="Kylin">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Java8">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://qiniu.codekylin.cn/github/img/img/博客封面19.png"><link rel="shortcut icon" href="https://qiniu.codekylin.cn/img/20200807181548.png"><link rel="canonical" href="https://www.codekylin.cn/27286"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//www.google-analytics.com" crossorigin=""/><link rel="preconnect" href="//hm.baidu.com"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin=""/><meta name="google-site-verification" content="gzeyWstt6NoTZKh7YFYNLNziL8HIZ8YH2Ug7xTDX5-Y"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?f76c34daefe747deee7c7be3ead2ba80";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-159334016-1"></script><script>window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-159334016-1');
</script><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"简"},
  noticeOutdate: {"limitDay":90,"position":"top","messagePrev":"自上次更新以来已经","messageNext":"天，文章的内容可能已过时或存在差异。"},
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":50000,"languages":{"author":"作者: Kylin","link":"链接: ","source":"来源: Kylin","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#FF0000","bgDark":"#2d3035","position":"bottom-left"},
  source: {
    jQuery: 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js',
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
    },
    fancybox: {
      js: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js',
      css: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isanchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = { 
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-07-12 19:42:50'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
          const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
          const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
          const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified

          if (t === undefined) {
            if (isLightMode) activateLightMode()
            else if (isDarkMode) activateDarkMode()
            else if (isNotSpecified || hasNoSupport) {
              const now = new Date()
              const hour = now.getHours()
              const isNight = hour <= 6 || hour >= 18
              isNight ? activateDarkMode() : activateLightMode()
            }
            window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
              if (saveToLocal.get('theme') === undefined) {
                e.matches ? activateDarkMode() : activateLightMode()
              }
            })
          } else if (t === 'light') activateLightMode()
          else activateDarkMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const fontSizeVal = saveToLocal.get('global-font-size')
    if (fontSizeVal !== undefined) {
      document.documentElement.style.setProperty('--global-font-size', fontSizeVal + 'px')
    }
    })(window)</script><link rel="stylesheet" href="https://qiniu.codekylin.cn/github/img/img/custom.css"><link rel="stylesheet" href="//at.alicdn.com/t/font_1993646_z05rabxf05h.css"><link rel="stylesheet" href="https://qiniu.codekylin.cn/github/img/img/icon.css"><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="Kylin" type="application/atom+xml">
</head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="author-avatar"><img class="avatar-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181526.jpg" onerror="onerror=null;src='https://qiniu.codekylin.cn/github/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/archives/"><div class="headline">文章</div><div class="length-num">362</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/tags/"><div class="headline">标签</div><div class="length-num">427</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/categories/"><div class="headline">分类</div><div class="length-num">101</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fa fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fa fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fa fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fa fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fa fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fa fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://qiniu.codekylin.cn/github/img/img/博客封面19.png')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">Kylin</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fa fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fa fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fa fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fa fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fa fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fa fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Java强大的Stream API</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-12-23T07:55:01.000Z" title="发表于 2020-12-23 15:55:01">2020-12-23</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-07-12T11:42:50.033Z" title="更新于 2022-07-12 19:42:50">2022-07-12</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java/">Java</a><i class="fas fa-angle-right post-meta-separator"></i><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java/Java8/">Java8</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">3.9k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>16分钟</span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h2 id="Stream-API说明"><a href="#Stream-API说明" class="headerlink" title="Stream API说明"></a>Stream API说明</h2><p>Java8中有两大最为重要的改变。第一个是<code>Lambda 表达式</code>;另外一个则是 <code>Stream API</code>。</p>
<p>Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这 是目前为止对Java类库最好的补充，因为Stream API可以极大提供Java程序员的生产力，让程序员写出高效率、干净、简洁的代码。</p>
<p>Stream 是 Java8 中处理集合的关键抽象概念，<strong>它可以指定你希望对集合进行的操作，可以执行非常复杂的查找、过滤和映射数据等操作。</strong> 使用 Stream API 对集合数据进行操作，就类似于使用 SQL 执行的数据库查询。 也可以使用 Stream API 来并行执行操作。简言之，Stream API 提供了一种 高效且易于使用的处理数据的方式。</p>
<h2 id="为什么要使用Stream-API"><a href="#为什么要使用Stream-API" class="headerlink" title="为什么要使用Stream API"></a>为什么要使用Stream API</h2><p>实际开发中，项目中多数数据源都来自于Mysql，Oracle等。但现在数据源可以更多了，有MongDB，Radis等，而这些NoSQL的数据就需要 Java层面去处理。</p>
<p>Stream 和 Collection 集合的区别:Collection 是一种静态的内存数据 结构，而 Stream 是有关计算的。前者是主要面向内存，存储在内存中， 后者主要是面向 CPU，通过 CPU 实现计算</p>
<p>但在当今这个数据大爆炸的时代，在数据来源多样化、数据海量化的今天，很多时候不得不脱离 RDBMS，或者以底层返回的数据为基础进行更上层的数据统计。而 Java 的集合 API 中，仅仅有极少量的辅助型方法，更多的时候是程序员需要用 Iterator 来遍历集合，完成相关的聚合应用逻辑。这是一种远不够高效、笨拙的方法。在 Java 7 中，如果要发现 type 为 grocery 的所有交易，然后返回以交易值降序排序好的交易 ID 集合，我们需要这样写：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Transaction&gt; groceryTransactions = <span class="keyword">new</span> Arraylist&lt;&gt;();</span><br><span class="line"><span class="keyword">for</span>(Transaction t: transactions)&#123;</span><br><span class="line"> <span class="keyword">if</span>(t.getType() == Transaction.GROCERY)&#123;</span><br><span class="line"> groceryTransactions.add(t);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line">Collections.sort(groceryTransactions, <span class="keyword">new</span> Comparator()&#123;</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compare</span><span class="params">(Transaction t1, Transaction t2)</span></span>&#123;</span><br><span class="line"> <span class="keyword">return</span> t2.getValue().compareTo(t1.getValue());</span><br><span class="line"> &#125;</span><br><span class="line">&#125;);</span><br><span class="line">List&lt;Integer&gt; transactionIds = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"><span class="keyword">for</span>(Transaction t: groceryTransactions)&#123;</span><br><span class="line"> transactionsIds.add(t.getId());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><mark><strong>而在 Java 8 使用 Stream，代码更加简洁易读；而且使用并发模式，程序执行速度更快。</strong></mark></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; transactionsIds = transactions.parallelStream().</span><br><span class="line"> filter(t -&gt; t.getType() == Transaction.GROCERY).</span><br><span class="line"> sorted(comparing(Transaction::getValue).reversed()).</span><br><span class="line"> map(Transaction::getId).</span><br><span class="line"> collect(toList());</span><br></pre></td></tr></table></figure>

<h2 id="什么是-Stream"><a href="#什么是-Stream" class="headerlink" title="什么是 Stream"></a>什么是 Stream</h2><p>Stream到底是什么呢? 是数据渠道，用于操作数据源(集合、数组等)所生成的元素序列。</p>
<blockquote>
<p> “集合讲的是数据，Stream讲的是计算!”</p>
</blockquote>
<p>注意:</p>
<ol>
<li><strong>Stream 自己不会存储元素。</strong></li>
<li><strong>Stream 不会改变源对象。相反，他们会返回一个持有结果的新Stream。</strong> </li>
<li><strong>Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。</strong></li>
</ol>
<h2 id="Stream的操作三个步骤"><a href="#Stream的操作三个步骤" class="headerlink" title="Stream的操作三个步骤"></a>Stream的操作三个步骤</h2><ol>
<li><p><strong>创建 Stream 一个数据源(如:集合、数组)，获取一个流</strong></p>
</li>
<li><p><strong>中间操作 一个中间操作链，对数据源的数据进行处理</strong></p>
</li>
<li><p><strong>终止操作(终端操作) 一旦执行终止操作，就执行中间操作链，并产生结果。之后，不会再被使用</strong></p>
</li>
</ol>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223161806766.png" alt="image-20201223161806766"></p>
<h2 id="创建Stream"><a href="#创建Stream" class="headerlink" title="创建Stream"></a>创建Stream</h2><p>首先创建一个<code>Employee</code>和<code>EmployeeData</code>类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Employee</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> id;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> age;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">double</span> salary;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">(<span class="keyword">int</span> id, String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.id = id;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">(<span class="keyword">int</span> id)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.id = id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">(<span class="keyword">int</span> id, String name, <span class="keyword">int</span> age, <span class="keyword">double</span> salary)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.id = id;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">        <span class="keyword">this</span>.age = age;</span><br><span class="line">        <span class="keyword">this</span>.salary = salary;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getAge</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Employee&#123;&quot;</span> +</span><br><span class="line">                <span class="string">&quot;id=&quot;</span> + id +</span><br><span class="line">                <span class="string">&quot;, name=&#x27;&quot;</span> + name + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&quot;, age=&quot;</span> + age +</span><br><span class="line">                <span class="string">&quot;, salary=&quot;</span> + salary +</span><br><span class="line">                <span class="string">&#x27;&#125;&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAge</span><span class="params">(<span class="keyword">int</span> age)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.age = age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getId</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setId</span><span class="params">(<span class="keyword">int</span> id)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.id = id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">getSalary</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> salary;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setSalary</span><span class="params">(<span class="keyword">int</span> salary)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.salary = salary;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object o)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span> == o) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        <span class="keyword">if</span> (o == <span class="keyword">null</span> || getClass() != o.getClass()) <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        Employee employee = (Employee) o;</span><br><span class="line">        <span class="keyword">return</span> id == employee.id &amp;&amp; age == employee.age &amp;&amp; Double.compare(employee.salary, salary) == <span class="number">0</span> &amp;&amp; Objects.equals(name, employee.name);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hashCode</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> Objects.hash(id, name, age, salary);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 提供用于测试的数据</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EmployeeData</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> List&lt;Employee&gt; <span class="title">getEmployees</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        List&lt;Employee&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1001</span>, <span class="string">&quot;马化腾&quot;</span>, <span class="number">34</span>, <span class="number">6000.38</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1002</span>, <span class="string">&quot;马云&quot;</span>, <span class="number">12</span>, <span class="number">9876.12</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1003</span>, <span class="string">&quot;刘强东&quot;</span>, <span class="number">33</span>, <span class="number">3000.82</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1004</span>, <span class="string">&quot;雷军&quot;</span>, <span class="number">26</span>, <span class="number">7657.37</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1005</span>, <span class="string">&quot;李彦宏&quot;</span>, <span class="number">65</span>, <span class="number">5555.32</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1006</span>, <span class="string">&quot;比尔盖茨&quot;</span>, <span class="number">42</span>, <span class="number">9500.43</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1007</span>, <span class="string">&quot;任正非&quot;</span>, <span class="number">26</span>, <span class="number">4333.32</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1008</span>, <span class="string">&quot;扎克伯格&quot;</span>, <span class="number">35</span>, <span class="number">2500.32</span>));</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="通过集合"><a href="#通过集合" class="headerlink" title="通过集合"></a>通过集合</h3><p>Java8 中的 Collection 接口被扩展，提供了两个获取流 的方法:</p>
<ul>
<li><code>default Stream&lt;E&gt; stream()</code>: 返回一个顺序流</li>
<li><code>default Stream&lt;E&gt; parallelStream()</code>: 返回一个并行流</li>
</ul>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223163836625.png" alt="image-20201223163836625"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建Steam方式一:通过集合</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">    <span class="comment">//default Stream&lt;E&gt; stream():返回一个顺序流</span></span><br><span class="line">    Stream&lt;Employee&gt; stream = employees.stream();</span><br><span class="line">    <span class="comment">//default Stream&lt;E&gt; parallelStream():返回一个并行流,并行操作。顺序不保证</span></span><br><span class="line">    Stream&lt;Employee&gt; parallelStream = employees.parallelStream();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="通过数组"><a href="#通过数组" class="headerlink" title="通过数组"></a>通过数组</h3><p>Java8 中的 Arrays 的静态方法 stream() 可以获取数组流: <code>static &lt;T&gt; Stream&lt;T&gt; stream(T[] array)</code>: 返回一个流</p>
<p>重载形式，能够处理对应基本类型的数组:</p>
<ul>
<li>public static IntStream stream(int[] array)</li>
<li>public static LongStream stream(long[] array)</li>
<li>public static DoubleStream stream(double[] array)</li>
</ul>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223164056077.png" alt="image-20201223164056077"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建Steam方式二:通过数组</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span>[] arr = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>&#125;;</span><br><span class="line">    <span class="comment">//调用Arrays类的public static &lt;T&gt; Stream&lt;T&gt; stream(T[] array) 返回一个流</span></span><br><span class="line">    IntStream stream = Arrays.stream(arr);</span><br><span class="line"></span><br><span class="line">    Employee e1 = <span class="keyword">new</span> Employee(<span class="number">1001</span>, <span class="string">&quot;Tom&quot;</span>);</span><br><span class="line">    Employee e2 = <span class="keyword">new</span> Employee(<span class="number">1001</span>, <span class="string">&quot;Jerry&quot;</span>);</span><br><span class="line">    Employee[] arr1 = &#123;e1, e2&#125;;</span><br><span class="line">    Stream&lt;Employee&gt; stream1 = Arrays.stream(arr1);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="通过Stream的of"><a href="#通过Stream的of" class="headerlink" title="通过Stream的of()"></a>通过Stream的of()</h3><p>可以调用Stream类静态方法 of(), 通过显示值创建一个 流。它可以接收任意数量的参数。</p>
<ul>
<li><code>public static&lt;T&gt; Stream&lt;T&gt; of(T... values)</code>: 返回一个流</li>
</ul>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223164227424.png" alt="image-20201223164227424"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建Stream方式三:通过Stream的of()</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    Stream&lt;Integer&gt; stream = Stream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="创建无限流"><a href="#创建无限流" class="headerlink" title="创建无限流"></a>创建无限流</h3><p>可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。</p>
<ul>
<li>迭代 <code>public static&lt;T&gt; Stream&lt;T&gt; iterate(final T seed, final UnaryOperator&lt;T&gt; f)</code></li>
<li>生成 <code>public static&lt;T&gt; Stream&lt;T&gt; generate(Supplier&lt;T&gt; s)</code></li>
</ul>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223164641197.png" alt="image-20201223164641197"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建 Stream方式四：创建无限流</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//迭代</span></span><br><span class="line">    <span class="comment">//public static&lt;T&gt; Stream&lt;T&gt; iterate(final T seed, final UnaryOperator&lt;T&gt; f)</span></span><br><span class="line">    <span class="comment">//遍历前10个偶数</span></span><br><span class="line">    Stream.iterate(<span class="number">0</span>, t -&gt; t + <span class="number">2</span>).limit(<span class="number">10</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//生成</span></span><br><span class="line">    <span class="comment">//public static&lt;T&gt; Stream&lt;T&gt; generate(Supplier&lt;T&gt; s)</span></span><br><span class="line">    Stream.generate(Math::random).limit(<span class="number">10</span>).forEach(System.out::println);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223164721180.png" alt="image-20201223164721180"></p>
<p>这里使用了后面会讲的其他Stream API操作。</p>
<h2 id="Stream的中间操作"><a href="#Stream的中间操作" class="headerlink" title="Stream的中间操作"></a>Stream的中间操作</h2><p>多个中间操作可以连接起来形成一个流水线，除非流水线上触发终止操作，否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理，称为“惰性求值”。</p>
<h3 id="筛选与切片"><a href="#筛选与切片" class="headerlink" title="筛选与切片"></a>筛选与切片</h3><p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223165522877.png" alt="image-20201223165522877"></p>
<table>
<thead>
<tr>
<th align="left">方法</th>
<th align="left">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="left">filter(Predicate p)</td>
<td align="left">接收 Lambda ， 从流中排除某些元素</td>
</tr>
<tr>
<td align="left">distinct()</td>
<td align="left">筛选，通过流所生成元素的 hashCode() 和 equals() 去除重复元素</td>
</tr>
<tr>
<td align="left">limit(long maxSize)</td>
<td align="left">截断流，使其元素不超过给定数量</td>
</tr>
<tr>
<td align="left">skip(long n)</td>
<td align="left">跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，则返回一 个空流。与 limit(n) 互补</td>
</tr>
</tbody></table>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223170218083.png" alt="image-20201223170218083"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1-筛选与切片</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    List&lt;Employee&gt; list = EmployeeData.getEmployees();</span><br><span class="line">    <span class="comment">//filter(Predicate p)——接收 Lambda ， 从流中排除某些元素。</span></span><br><span class="line">    Stream&lt;Employee&gt; stream = list.stream();</span><br><span class="line">    <span class="comment">//练习：查询员工表中薪资大于7000的员工信息</span></span><br><span class="line">    stream.filter(employee -&gt; employee.getSalary() &gt; <span class="number">7000</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="comment">//limit(n)——截断流，使其元素不超过给定数量。</span></span><br><span class="line">    list.stream().limit(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="comment">//skip(n) —— 跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，则返回一个空流。与 limit(n) 互补</span></span><br><span class="line">    list.stream().skip(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="comment">//distinct()——筛选，通过流所生成元素的 hashCode() 和 equals() 去除重复元素</span></span><br><span class="line">    list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>, <span class="string">&quot;刘强东&quot;</span>, <span class="number">40</span>, <span class="number">8000</span>));</span><br><span class="line">    list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>, <span class="string">&quot;刘强东&quot;</span>, <span class="number">41</span>, <span class="number">8000</span>));</span><br><span class="line">    list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>, <span class="string">&quot;刘强东&quot;</span>, <span class="number">40</span>, <span class="number">8000</span>));</span><br><span class="line">    list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>, <span class="string">&quot;刘强东&quot;</span>, <span class="number">40</span>, <span class="number">8000</span>));</span><br><span class="line">    list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>, <span class="string">&quot;刘强东&quot;</span>, <span class="number">40</span>, <span class="number">8000</span>));</span><br><span class="line">    System.out.println(list);</span><br><span class="line">    System.out.println();</span><br><span class="line"></span><br><span class="line">    list.stream().distinct().forEach(System.out::println);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223170313157.png" alt="image-20201223170313157"></p>
<h3 id="映射"><a href="#映射" class="headerlink" title="映射"></a>映射</h3><p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223170355480.png" alt="image-20201223170355480"></p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td><strong>map(Function f)</strong></td>
<td><strong>接收一个函数作为参数，该函数会被应用到每个元 素上，并将其映射成一个新的元素。</strong></td>
</tr>
<tr>
<td>mapToDouble(ToDoubleFunction f)</td>
<td>接收一个函数作为参数，该函数会被应用到每个元 素上，产生一个新的 DoubleStream。</td>
</tr>
<tr>
<td>mapToInt(ToIntFunction f)</td>
<td>接收一个函数作为参数，该函数会被应用到每个元 素上，产生一个新的 IntStream。</td>
</tr>
<tr>
<td>mapToLong(ToLongFunction f)</td>
<td>接收一个函数作为参数，该函数会被应用到每个元 素上，产生一个新的 LongStream。</td>
</tr>
<tr>
<td><strong>flatMap(Function f)</strong></td>
<td><strong>接收一个函数作为参数，将流中的每个值都换成另 一个流，然后把所有流连接成一个流</strong></td>
</tr>
</tbody></table>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223172413660.png" alt="image-20201223172413660"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//映射</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">//map(Function f)——---&gt;接收一个函数作为参数，将元素转换成其他形式或提取信息，该函数会被应用到每个元素上，并将其映射成一个新的元素。</span></span><br><span class="line">    List&lt;String&gt; list = Arrays.asList(<span class="string">&quot;aa&quot;</span>, <span class="string">&quot;bb&quot;</span>, <span class="string">&quot;cc&quot;</span>, <span class="string">&quot;dd&quot;</span>);</span><br><span class="line">    list.stream().map(<span class="keyword">new</span> Function&lt;String, String&gt;() &#123;</span><br><span class="line"></span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> String <span class="title">apply</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> s.toUpperCase();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    list.stream().map(str -&gt; str.toUpperCase()).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">////练习1：获取员工姓名长度大于3的员工的姓名。</span></span><br><span class="line">    List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">    employees.stream().map(employee -&gt; employee.getName()).filter(name -&gt; name.length() &gt; <span class="number">3</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println();</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201223172505470.png" alt="image-20201223172505470"></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/flatMap.png" alt="flatMap"></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/format,png.jpeg" alt="img"></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/format,png-20201224111632356.jpeg" alt="img"></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224111417560.png" alt="image-20201224111417560"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//练习2：</span></span><br><span class="line">    <span class="comment">//Function&lt;T, R&gt;:R                  apply(T t);</span></span><br><span class="line">    <span class="comment">//              :Stream&lt;Character&gt;  fromStringToStream(String s)</span></span><br><span class="line"></span><br><span class="line">    List&lt;String&gt; list = Arrays.asList(<span class="string">&quot;aa&quot;</span>, <span class="string">&quot;bb&quot;</span>, <span class="string">&quot;cc&quot;</span>, <span class="string">&quot;dd&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//Stream&lt;Stream&lt;Character&gt;&gt; stream = list.stream().map(s -&gt; fromStringToStream(s));</span></span><br><span class="line">    Stream&lt;Stream&lt;Character&gt;&gt; streamStream = list.stream().map(StreamAPITest1::fromStringToStream);</span><br><span class="line"></span><br><span class="line">    streamStream.forEach(s -&gt; &#123;</span><br><span class="line">        s.forEach(System.out::println);</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println();</span><br><span class="line"></span><br><span class="line">    <span class="comment">//flatMap(Function f)——接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。</span></span><br><span class="line">    Stream&lt;Character&gt; characterStream = list.stream().flatMap(StreamAPITest1::fromStringToStream);</span><br><span class="line">    characterStream.forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//将字符串中的多个字符构成的集合转换为对应的Stream的实例</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Stream&lt;Character&gt; <span class="title">fromStringToStream</span><span class="params">(String str)</span> </span>&#123;<span class="comment">//aa</span></span><br><span class="line">    ArrayList&lt;Character&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="comment">//将str变成Char[]数组，依次遍历添加到list中。</span></span><br><span class="line">    <span class="keyword">for</span> (Character c : str.toCharArray()) &#123;</span><br><span class="line">        list.add(c);<span class="comment">//a,a</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> list.stream();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224111741283.png" alt="image-20201224111741283"></p>
<h3 id="排序"><a href="#排序" class="headerlink" title="排序"></a>排序</h3><p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224111907734.png" alt="image-20201224111907734"></p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>sorted()</td>
<td>产生一个新流，其中按自然顺序排序</td>
</tr>
<tr>
<td>Sorted(Comparator com)</td>
<td>产生一个新流，其中按比较器顺序排序</td>
</tr>
</tbody></table>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224112214548.png" alt="image-20201224112214548"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test5</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">//sorted()——自然排序</span></span><br><span class="line">    List&lt;Integer&gt; list = Arrays.asList(<span class="number">12</span>, <span class="number">43</span>, <span class="number">65</span>, <span class="number">34</span>, <span class="number">87</span>, <span class="number">0</span>, -<span class="number">98</span>, <span class="number">7</span>);</span><br><span class="line">    list.stream().sorted().forEach(System.out::println);</span><br><span class="line">    <span class="comment">//抛异常，原因:Employee没有实现Comparable接口</span></span><br><span class="line">    <span class="comment">//List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span></span><br><span class="line">    <span class="comment">//employees.stream().sorted().forEach(System.out::println);</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">//sorted(Comparator com)——定制排序</span></span><br><span class="line"></span><br><span class="line">    List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">    employees.stream().sorted((e1, e2) -&gt; &#123;</span><br><span class="line">        <span class="comment">//年龄排序</span></span><br><span class="line">        <span class="keyword">int</span> ageValue = Integer.compare(e1.getAge(), e2.getAge());</span><br><span class="line">        <span class="keyword">if</span> (ageValue != <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> ageValue;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> -Double.compare(e1.getSalary(), e2.getSalary());</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224112325830.png" alt="image-20201224112325830"></p>
<h2 id="终止操作"><a href="#终止操作" class="headerlink" title="终止操作"></a>终止操作</h2><p>终止操作会从流的流水线生成结果。其结果可以是任何不是流的值，例如:List、Integer，甚至是 void 。<mark>流进行了终止操作后，不能再次使用。</mark></p>
<h3 id="匹配与查找"><a href="#匹配与查找" class="headerlink" title="匹配与查找"></a>匹配与查找</h3><p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224112547700.png" alt="image-20201224112547700"></p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>allMatch(Predicate p)</td>
<td>检查是否匹配所有元素</td>
</tr>
<tr>
<td>anyMatch(Predicate p)</td>
<td>检查是否至少匹配一个元素</td>
</tr>
<tr>
<td>noneMatch(Predicate p)</td>
<td>检查是否没有匹配所有元素</td>
</tr>
<tr>
<td>findFirst()</td>
<td>返回第一个元素</td>
</tr>
<tr>
<td>findAny()</td>
<td>返回当前流中的任意元素</td>
</tr>
</tbody></table>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224112823507.png" alt="image-20201224112823507"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1-匹配与查找</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">    <span class="comment">//allMatch(Predicate p)——检查是否匹配所有元素。</span></span><br><span class="line">    <span class="comment">//  练习：是否所有的员工的年龄都大于18</span></span><br><span class="line">    System.out.println(employees.stream().allMatch(employee -&gt; employee.getAge() &gt; <span class="number">18</span>));</span><br><span class="line"></span><br><span class="line">    <span class="comment">//anyMatch(Predicate p)——检查是否至少匹配一个元素。</span></span><br><span class="line">    <span class="comment">// 练习：是否存在员工的工资大于 10000</span></span><br><span class="line">    System.out.println(employees.stream().anyMatch(employee -&gt; employee.getSalary() &gt; <span class="number">10000</span>));</span><br><span class="line"></span><br><span class="line">    <span class="comment">//noneMatch(Predicate p)——检查是否没有匹配的元素。</span></span><br><span class="line">    <span class="comment">//   练习：是否存在员工姓“雷”</span></span><br><span class="line">    System.out.println(employees.stream().noneMatch(employee -&gt; employee.getName().startsWith(<span class="string">&quot;雷&quot;</span>)));</span><br><span class="line"></span><br><span class="line">    <span class="comment">//findFirst——返回第一个元素</span></span><br><span class="line">    Optional&lt;Employee&gt; employee = employees.stream().findFirst();</span><br><span class="line">    System.out.println(employee);</span><br><span class="line">    <span class="comment">//findAny——返回当前流中的任意元素</span></span><br><span class="line">    Optional&lt;Employee&gt; employee1 = employees.parallelStream().findAny();</span><br><span class="line">    System.out.println(employee1);</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224112938333.png" alt="image-20201224112938333"></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224114305591.png" alt="image-20201224114305591"></p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>count()</td>
<td>返回流中元素总数</td>
</tr>
<tr>
<td>max(Comparator c)</td>
<td>返回流中最大值</td>
</tr>
<tr>
<td>min(Comparator c)</td>
<td>返回流中最小值</td>
</tr>
<tr>
<td>forEach(Consumer c)</td>
<td>内部迭代(使用 Collection 接口需要用户去做迭代 称为外部迭代。相反，Stream API 使用内部迭 代——它帮你把迭代做了)</td>
</tr>
</tbody></table>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224114839122.png" alt="image-20201224114839122"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">    <span class="comment">// count——返回流中元素的总个数</span></span><br><span class="line">    <span class="keyword">long</span> count = employees.stream().filter(e -&gt; e.getSalary() &gt; <span class="number">5000</span>).count();</span><br><span class="line">    System.out.println(count);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//max(Comparator c)——返回流中最大值</span></span><br><span class="line">    <span class="comment">//练习：返回最高的工资：</span></span><br><span class="line">    Stream&lt;Double&gt; salaryStream = employees.stream().map(e -&gt; e.getSalary());</span><br><span class="line">    Optional&lt;Double&gt; maxSalary = salaryStream.max(Double::compare);</span><br><span class="line">    System.out.println(maxSalary);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//min(Comparator c)——返回流中最小值</span></span><br><span class="line">    <span class="comment">//练习：返回最低工资的员工</span></span><br><span class="line">    Optional&lt;Employee&gt; employee = employees.stream().min((e1, e2) -&gt; Double.compare(e1.getSalary(), e2.getSalary()));</span><br><span class="line">    System.out.println(employee);</span><br><span class="line">    System.out.println();</span><br><span class="line">    <span class="comment">//forEach(Consumer c)——内部迭代</span></span><br><span class="line">    employees.stream().forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//使用集合的遍历操作</span></span><br><span class="line">    employees.forEach(System.out::println);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224115003442.png" alt="image-20201224115003442"></p>
<h3 id="归约"><a href="#归约" class="headerlink" title="归约"></a>归约</h3><p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224115130556.png" alt="image-20201224115130556"></p>
<p><strong>备注:map 和 reduce 的连接通常称为 map-reduce 模式，因 Google 用它来进行网络搜索而出名</strong>。</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>reduce(T iden, BinaryOperator b)</td>
<td>可以将流中元素反复结合起来，得到一 个值。返回 T</td>
</tr>
<tr>
<td>reduce(BinaryOperator b)</td>
<td>可以将流中元素反复结合起来，得到一 个值。返回 Optional<T></td>
</tr>
</tbody></table>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224115657791.png" alt="image-20201224115657791"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//2-归约</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">//reduce(T identity, BinaryOperator)——可以将流中元素反复结合起来，得到一个值。返回 T</span></span><br><span class="line">    <span class="comment">//练习1：计算1-10的自然数的和</span></span><br><span class="line">    List&lt;Integer&gt; list = Arrays.asList(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>, <span class="number">10</span>);</span><br><span class="line">    Integer sum = list.stream().reduce(<span class="number">0</span>, Integer::sum);</span><br><span class="line">    System.out.println(sum);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//reduce(BinaryOperator) ——可以将流中元素反复结合起来，得到一个值。返回 Optional&lt;T&gt;</span></span><br><span class="line">    <span class="comment">//练习2：计算公司所有员工工资的总和</span></span><br><span class="line">    List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">    Stream&lt;Double&gt; salaryStream = employees.stream().map(Employee::getSalary);</span><br><span class="line">    <span class="comment">//Optional&lt;Double&gt; sumMoney = salaryStream.reduce(Double::sum);</span></span><br><span class="line">    Optional&lt;Double&gt; sumMoney = salaryStream.reduce((d1, d2) -&gt; d1 + d2);</span><br><span class="line">    System.out.println(sumMoney.get());</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224125409801.png" alt="image-20201224125409801"></p>
<h3 id="收集"><a href="#收集" class="headerlink" title="收集"></a>收集</h3><p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224125553593.png" alt="image-20201224125553593"></p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>collect(Collector c)</td>
<td>将流转换为其他形式。接收一个 Collector 接口的实现，用于给Stream中元素做汇总 的方法</td>
</tr>
</tbody></table>
<p>Collector 接口中方法的实现决定了如何对流执行收集的操作(如收集到 List、Set、 Map)。</p>
<p>另外， Collectors 实用类提供了很多静态方法，可以方便地创建常见收集器实例， 具体方法与实例如下表:</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224125737423.png" alt="image-20201224125737423"></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224125752696.png" alt="image-20201224125752696"></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224125819140.png" alt="image-20201224125819140"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">    <span class="comment">//3-收集</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">//collect(Collector c)——将流转换为其他形式。接收一个 Collector接口的实现，用于给Stream中元素做汇总的方法</span></span><br><span class="line">        <span class="comment">//练习1：查找工资大于6000的员工，结果返回为一个List或Set</span></span><br><span class="line">        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">        <span class="comment">//List</span></span><br><span class="line">        List&lt;Employee&gt; employeeList = employees.stream().filter(e -&gt; e.getSalary() &gt; <span class="number">6000</span>).collect(Collectors.toList());</span><br><span class="line">        employeeList.forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">        System.out.println();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//Set</span></span><br><span class="line">        Set&lt;Employee&gt; employeeSet = employees.stream().filter(e -&gt; e.getSalary() &gt; <span class="number">6000</span>).collect(Collectors.toSet());</span><br><span class="line">        employeeSet.forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://qiniu.codekylin.cn/img/image-20201224125844332.png" alt="image-20201224125844332"></p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">Kylin</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://www.codekylin.cn/27286.html">https://www.codekylin.cn/27286.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://www.codekylin.cn" target="_blank">Kylin</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Java/">Java</a><a class="post-meta__tags" href="/tags/Java8/">Java8</a></div><div class="post_share"><div class="social-share" data-image="https://qiniu.codekylin.cn/github/img/img/博客封面19.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button button--animated"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://qiniu.codekylin.cn/img/20200807181442.jpg" target="_blank"><img class="post-qr-code-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181442.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="https://qiniu.codekylin.cn/img/20200807181505.jpg" target="_blank"><img class="post-qr-code-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181505.jpg" alt="支付寶"/></a><div class="post-qr-code-desc">支付寶</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/60845.html"><img class="prev-cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-g8dzme.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Java之Optional类</div></div></a></div><div class="next-post pull-right"><a href="/2936.html"><img class="next-cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-dgzqkl.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Java构造器和数组引用</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span> 相关推荐</span></div><div class="relatedPosts-list"><div><a href="/60845.html" title="Java之Optional类"><img class="cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-g8dzme.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-12-24</div><div class="title">Java之Optional类</div></div></a></div><div><a href="/27952.html" title="Java之方法引用"><img class="cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-j5j6r5.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-12-21</div><div class="title">Java之方法引用</div></div></a></div><div><a href="/2936.html" title="Java构造器和数组引用"><img class="cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-dgzqkl.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-12-23</div><div class="title">Java构造器和数组引用</div></div></a></div><div><a href="/20251.html" title="JUC之ABA问题"><img class="cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/荒鲸.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-09-26</div><div class="title">JUC之ABA问题</div></div></a></div><div><a href="/25239.html" title="JUC之CAS原理"><img class="cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/博客封面14.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-09-26</div><div class="title">JUC之CAS原理</div></div></a></div><div><a href="/60468.html" title="JUC之Callable接口"><img class="cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-0pvrpm.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-09-27</div><div class="title">JUC之Callable接口</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div class="vcomment" id="vcomment"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="card-info-avatar is-center"><img class="avatar-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181526.jpg" onerror="this.onerror=null;this.src='https://qiniu.codekylin.cn/github/img/friend_404.gif'" alt="avatar"/><div class="author-info__name">Kylin</div><div class="author-info__description">学习不易，努力努力~</div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">362</div></a></div><div class="card-info-data-item is-center"><a href="/tags/"><div class="headline">标签</div><div class="length-num">427</div></a></div><div class="card-info-data-item is-center"><a href="/categories/"><div class="headline">分类</div><div class="length-num">101</div></a></div></div><a class="button--animated" id="card-info-btn"><i class="fas fa-bookmark"></i><span>加入书签</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/kylincw" target="_blank" title="Github"><i class="iconfont icon-github"></i></a><a class="social-icon" href="tencent://message/?Menu=yes&amp;uin=171346168&amp;Service=300&amp;sigT=45a1e5847943b64c6ff3990f8a9e644d2b31356cb0b4ac6b24663a3c8dd0f8aa12a595b1714f9d45" target="_blank" title="qq"><i class="iconfont icon-qq"></i></a><a class="social-icon" href="https://space.bilibili.com/53836035" target="_blank" title="BiliBili"><i class="iconfont icon-bilibili-line"></i></a><a class="social-icon" href="mailto:zhang171346168@qq.com" target="_blank" title="Email"><i class="iconfont icon-email1"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="iconfont icon-rss"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>公告</span></div><div class="announcement_content">学习不易，努力努力！</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#Stream-API%E8%AF%B4%E6%98%8E"><span class="toc-number">1.</span> <span class="toc-text">Stream API说明</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BD%BF%E7%94%A8Stream-API"><span class="toc-number">2.</span> <span class="toc-text">为什么要使用Stream API</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-Stream"><span class="toc-number">3.</span> <span class="toc-text">什么是 Stream</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Stream%E7%9A%84%E6%93%8D%E4%BD%9C%E4%B8%89%E4%B8%AA%E6%AD%A5%E9%AA%A4"><span class="toc-number">4.</span> <span class="toc-text">Stream的操作三个步骤</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%9B%E5%BB%BAStream"><span class="toc-number">5.</span> <span class="toc-text">创建Stream</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%9A%E8%BF%87%E9%9B%86%E5%90%88"><span class="toc-number">5.1.</span> <span class="toc-text">通过集合</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%9A%E8%BF%87%E6%95%B0%E7%BB%84"><span class="toc-number">5.2.</span> <span class="toc-text">通过数组</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%9A%E8%BF%87Stream%E7%9A%84of"><span class="toc-number">5.3.</span> <span class="toc-text">通过Stream的of()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E6%97%A0%E9%99%90%E6%B5%81"><span class="toc-number">5.4.</span> <span class="toc-text">创建无限流</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Stream%E7%9A%84%E4%B8%AD%E9%97%B4%E6%93%8D%E4%BD%9C"><span class="toc-number">6.</span> <span class="toc-text">Stream的中间操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AD%9B%E9%80%89%E4%B8%8E%E5%88%87%E7%89%87"><span class="toc-number">6.1.</span> <span class="toc-text">筛选与切片</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%98%A0%E5%B0%84"><span class="toc-number">6.2.</span> <span class="toc-text">映射</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8E%92%E5%BA%8F"><span class="toc-number">6.3.</span> <span class="toc-text">排序</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%88%E6%AD%A2%E6%93%8D%E4%BD%9C"><span class="toc-number">7.</span> <span class="toc-text">终止操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8C%B9%E9%85%8D%E4%B8%8E%E6%9F%A5%E6%89%BE"><span class="toc-number">7.1.</span> <span class="toc-text">匹配与查找</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BD%92%E7%BA%A6"><span class="toc-number">7.2.</span> <span class="toc-text">归约</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%94%B6%E9%9B%86"><span class="toc-number">7.3.</span> <span class="toc-text">收集</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/56352.html" title="be动词"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/博客封面10.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="be动词"/></a><div class="content"><a class="title" href="/56352.html" title="be动词">be动词</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/36436.html" title="JVM堆内存"><img data-lazy-src="https://qiniu.codekylin.cn/img/20200418115059.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="JVM堆内存"/></a><div class="content"><a class="title" href="/36436.html" title="JVM堆内存">JVM堆内存</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/44292.html" title="Java多线程详解"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-eorjzk.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Java多线程详解"/></a><div class="content"><a class="title" href="/44292.html" title="Java多线程详解">Java多线程详解</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/40200.html" title="谷粒商城记录"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-6qvvrx.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="谷粒商城记录"/></a><div class="content"><a class="title" href="/40200.html" title="谷粒商城记录">谷粒商城记录</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/27082.html" title="Spring学习-3"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-4x28xo.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Spring学习-3"/></a><div class="content"><a class="title" href="/27082.html" title="Spring学习-3">Spring学习-3</a><time datetime="2022-07-12T11:47:29.799Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('https://qiniu.codekylin.cn/github/img/img/博客封面19.png')"><div id="footer-wrap"><div class="copyright">&copy;2019 - 2022 By Kylin</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text"><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/"><img class="icp-icon" src="https://img.alicdn.com/tfs/TB1..50QpXXXXX7XpXXXXXXXXXX-40-40.png"><span>湘ICP备2022005420号-1</span></a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="font-plus" type="button" title="放大字体"><i class="fas fa-plus"></i></button><button id="font-minus" type="button" title="缩小字体"><i class="fas fa-minus"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div></div><hr/><div id="local-search-results"></div><span class="search-close-button"><i class="fas fa-times"></i></span></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"><script>function loadValine () {
  function initValine () {
    const valine = new Valine(Object.assign({
      el: '#vcomment',
      appId: 'ClIyIUhj1ue2rcRTsApYCR50-gzGzoHsz',
      appKey: 'ATug9IScYQBHILhKWEqBHYxM',
      placeholder: '昵称填入QQ号能获取到QQ头像哦~请输入正确的邮箱地址，你将会快速收到我的回复并且通过邮件通知你！~',
      avatar: 'robohash',
      meta: 'nick,mail,link'.split(','),
      pageSize: '10',
      lang: 'zh-cn',
      recordIP: false,
      serverURLs: 'https://cliyiuhj.lc-cn-n1-shared.com',
      emojiCDN: '',
      emojiMaps: "",
      enableQQ: true,
      path: window.location.pathname,
      requiredFields: ["nick,mail"],
      visitor: false
    }, null))
  }

  if (typeof Valine === 'function') initValine() 
  else getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js').then(initValine)
}

if ('Valine' === 'Valine' || !true) {
  if (true) btf.loadComment(document.getElementById('vcomment'),loadValine)
  else setTimeout(loadValine, 0)
} else {
  function loadOtherComment () {
    loadValine()
  }
}</script></div><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="true"></script><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-fluttering-ribbon.min.js"></script></div></body></html>